package 笔试.天融信;

import java.util.Arrays;
import java.util.Stack;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author:谢君臣
 * @Date:2021/10/16-18:52
 * @version:1.0
 * @function:
 */
public class Main {
    public static void main(String[] args) {
        FizzBuzz f = new FizzBuzz(10);
        f.buzz();
        f.fizz();
        f.fizzbuzz();
        f.number();
    }

    private static void function(int[][] arr) {
        Arrays.sort(arr,(p,q)->{
            if (p[0]!=q[0]) {
                return p[0]-q[0];
            }else {
                return q[1]-p[1];
            }
        });
        int ans = 0;
        Stack<int[]> stack = new Stack<>();
        for (int i = arr.length-1; i >=0 ; i--) {
            while (!stack.isEmpty()) {
                if (stack.peek()[0]>arr[i][0] && stack.peek()[1]> arr[i][1]) {
                    break;
                }
                stack.pop();
            }
            if (stack.size()>0) {
                ans++;
            }
            stack.push(arr[i]);
        }
        System.out.println(ans);
    }
}
class FizzBuzz {
    ReentrantLock lock = new ReentrantLock();
    Condition c1 = lock.newCondition();
    Condition c2 = lock.newCondition();
    Condition c3 = lock.newCondition();
    Condition c4 = lock.newCondition();
    private volatile int i=1;
    private int n;
    public FizzBuzz(int n) {
        this.n= n;
    }               // constructor

    //printFizz
    public void fizz() {
        new Thread(()->{
            while (i<=n){
                lock.lock();
                try {
                    if (i%3==0&&i%5==0){
                        c3.signal();
                    }else if (i%3==0){
                        System.out.print("Fizz,");
                        i++;
                    }else if (i%5==0){
                        c2.signal();
                    }else {
                        c4.signal();
                    }
                    c1.await();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
    }// only output "fizz"

    //printBuzz
    public void buzz() {
        new Thread(()->{
            while (i<=n){
                lock.lock();
                try {
                    if (i%3==0&&i%5==0){
                        c3.signal();
                    }else if (i%3==0){
                        c1.signal();
                    }else if (i%5==0){
                        System.out.print("Buzz,");
                        i++;
                    }else {
                        c4.signal();
                    }
                    c2.await();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
    }          // only output "buzz"

    //printFizzBuzz
    public void fizzbuzz() {
        new Thread(()->{
            while (i<=n){
                lock.lock();
                try {
                    if (i%3==0&&i%5==0){
                        System.out.print("fizzbuzz,");
                        i++;
                    }else if (i%3==0){
                        c1.signal();
                    }else if (i%5==0){
                        c2.signal();
                    }else {
                        c4.signal();
                    }
                    c3.await();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
    }  // only output "fizzbuzz"

    //printNumber
    public void number() {
        new Thread(()->{
            while (i<=n){
                lock.lock();
                try {
                    if (i%3==0&&i%5==0){
                        c3.signal();
                    }else if (i%3==0){
                        c1.signal();
                    }else if (i%5==0){
                        c2.signal();
                    }else{
                        System.out.print(i+",");
                        i++;
                    }
                    c4.await();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
    }      // only output the numbers

}